package com.yfqy.app.modules.address.serviceimpl;

import cn.hutool.core.collection.CollUtil;
import com.yfqy.app.configure.Idgenerator.SnowflakeIdGenerator;
import com.yfqy.app.domain.entity.Area;
import com.yfqy.app.domain.entity.CustomerAddress;
import com.yfqy.app.domain.mapper.AreaMapper;
import com.yfqy.app.domain.mapper.CustomerAddressMapper;
import com.yfqy.app.enums.AreaStatus;
import com.yfqy.app.enums.ErrorCode;
import com.yfqy.app.exception.BusinessException;
import com.yfqy.app.modules.address.dto.AreaQueryDTO;
import com.yfqy.app.modules.address.dto.AreaValidationResult;
import com.yfqy.app.modules.address.dto.DeliveryAddressDTO;
import com.yfqy.app.modules.address.service.AddressService;
import com.yfqy.app.modules.address.vo.AreaVO;
import com.yfqy.app.modules.address.vo.DeliveryAddressVO;
import com.yfqy.app.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.Collator;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AddressServiceImpl extends UserService implements AddressService {

    @Autowired
    private CustomerAddressMapper addressMapper;
    @Autowired
    private SnowflakeIdGenerator idGenerator;
    @Autowired
    private AreaMapper areaMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addAddress(DeliveryAddressDTO addressDTO) {
        Long customerId = getUserId();

        // 验证区域信息
        AreaValidationResult areaResult = validateAreas(
                addressDTO.getProvinceId(),
                addressDTO.getCityId(),
                addressDTO.getDistrictId()
        );

        // 处理默认地址
        handleDefaultAddress(customerId, addressDTO.getIsDefault());

        // 创建地址记录
        CustomerAddress address = buildCustomerAddress(addressDTO, customerId, areaResult);

        addressMapper.insert(address);
        log.info("新增收货地址成功，用户ID: {}, 地址ID: {}", customerId, address.getId());

        return address.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAddress(Long addressId, DeliveryAddressDTO addressDTO) {
        Long customerId = getUserId();

        // 验证地址存在性和权限
        CustomerAddress existingAddress = validateAddressOwnership(addressId, customerId);

        // 验证区域信息
        AreaValidationResult areaResult = validateAreas(
                addressDTO.getProvinceId(),
                addressDTO.getCityId(),
                addressDTO.getDistrictId()
        );

        // 处理默认地址
        handleDefaultAddress(customerId, addressDTO.getIsDefault());

        // 更新地址信息
        updateCustomerAddress(existingAddress, addressDTO, areaResult);

        addressMapper.updateByPrimaryKeySelective(existingAddress);
        log.info("更新收货地址成功，用户ID: {}, 地址ID: {}", customerId, addressId);
    }

    /**
     * 验证区域信息
     */
    private AreaValidationResult validateAreas(Integer provinceId, Integer cityId, Integer districtId) {
        Area province = getAndValidateArea(provinceId, "省份");
        Area city = getAndValidateArea(cityId, "城市");
        Area district = getAndValidateArea(districtId, "区域");

        // 可选：验证区域层级关系
        validateAreaHierarchy(province, city, district);

        return new AreaValidationResult(province, city, district);
    }

    /**
     * 获取并验证单个区域
     */
    private Area getAndValidateArea(Integer areaId, String areaType) {

        Area area = areaMapper.selectByPrimaryKey(areaId);
        if (area == null) {
            log.warn("{}不存在，ID: {}", areaType, areaId);
            throw new BusinessException(ErrorCode.AREA_NOT_EXIST.getCode(), areaType + "不存在");
        }

        if (AreaStatus.CLOSED.getStatus() == area.getIsOpen()) {
            log.warn("{}已关闭，ID: {}", areaType, areaId);
            throw new BusinessException(ErrorCode.AREA_NOT_AVAILABLE.getCode(), areaType + "暂不支持配送");
        }

        return area;
    }

    /**
     * 验证区域层级关系（可选）
     */
    private void validateAreaHierarchy(Area province, Area city, Area district) {
        // 这里可以添加区域层级验证逻辑
        // 例如：验证城市是否属于省份，区域是否属于城市等
        // 根据具体的区域数据表结构来实现
    }

    /**
     * 验证地址所有权
     */
    private CustomerAddress validateAddressOwnership(Long addressId, Long customerId) {

        CustomerAddress address = addressMapper.selectByPrimaryKey(addressId);
        if (address == null) {
            log.warn("收货地址不存在，地址ID: {}", addressId);
            throw new BusinessException(ErrorCode.AREA_NOT_EXIST);
        }

        if (!address.getCustomerId().equals(customerId)) {
            log.warn("用户无权限操作该地址，用户ID: {}, 地址ID: {}", customerId, addressId);
            throw new BusinessException(ErrorCode.ADDRESS_NO_PERMISSION);
        }

        if (address.getStatus() == AreaStatus.CLOSED.getStatus()) {
            log.warn("收货地址已删除，地址ID: {}", addressId);
            throw new BusinessException(ErrorCode.ADDRESS_DELETED);
        }

        return address;
    }

    /**
     * 处理默认地址
     */
    private void handleDefaultAddress(Long customerId, Boolean isDefault) {
        if (Boolean.TRUE.equals(isDefault)) {
            int clearedCount = addressMapper.clearDefaultFlag(customerId);
            log.debug("清除用户默认地址，用户ID: {}, 清除数量: {}", customerId, clearedCount);
        }
    }

    /**
     * 构建收货地址对象
     */
    private CustomerAddress buildCustomerAddress(DeliveryAddressDTO addressDTO,
                                                 Long customerId,
                                                 AreaValidationResult areaResult) {
        CustomerAddress address = new CustomerAddress();
        BeanUtils.copyProperties(addressDTO, address);

        address.setId(idGenerator.nextId());
        address.setCustomerId(customerId);
        address.setReceiverProvince(areaResult.getProvince().getAreaName());
        address.setReceiverCity(areaResult.getCity().getAreaName());
        address.setReceiverDistrict(areaResult.getDistrict().getAreaName());
        address.setAreaId(areaResult.getDistrict().getId());

        return address;
    }

    /**
     * 更新收货地址对象
     */
    private void updateCustomerAddress(CustomerAddress address,
                                       DeliveryAddressDTO addressDTO,
                                       AreaValidationResult areaResult) {
        BeanUtils.copyProperties(addressDTO, address);

        address.setReceiverProvince(areaResult.getProvince().getAreaName());
        address.setReceiverCity(areaResult.getCity().getAreaName());
        address.setReceiverDistrict(areaResult.getDistrict().getAreaName());
        address.setAreaId(areaResult.getDistrict().getId());
    }

    @Override
    public void deleteAddress(Long addressId) {
        Long customerId = getUserId();
        CustomerAddress address = addressMapper.selectByPrimaryKey(addressId);
        if (address == null
                || address.getStatus() == AreaStatus.CLOSED.getStatus()
                || !address.getCustomerId().equals(customerId)) {
            throw new BusinessException(ErrorCode.ADDRESS_NO_PERMISSION);
        }
        // 逻辑删除
        addressMapper.deleteAddress(addressId);
    }

    @Override
    public DeliveryAddressVO getAddressDetail(Long addressId) {
        Long customerId = getUserId();
        CustomerAddress address = addressMapper.selectByPrimaryKey(addressId);
        if (address == null
                || address.getStatus() == AreaStatus.CLOSED.getStatus()
                || !address.getCustomerId().equals(customerId)) {
            throw new BusinessException(ErrorCode.ADDRESS_NO_PERMISSION);
        }
        DeliveryAddressVO vo = new DeliveryAddressVO();
        BeanUtils.copyProperties(address, vo);
        return vo;
    }

    @Override
    public List<DeliveryAddressVO> customerAddress() {
        Long customerId = getUserId();
        List<CustomerAddress> addresses = addressMapper.customerAddress(customerId);
        return addresses.stream().map(address -> {
            DeliveryAddressVO vo = new DeliveryAddressVO();
            BeanUtils.copyProperties(address, vo);
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setDefaultAddress(Long addressId) {
        Long customerId = getUserId();
        CustomerAddress address = addressMapper.selectByPrimaryKey(addressId);
        if (address == null
                || address.getStatus() == AreaStatus.CLOSED.getStatus()
                || !address.getCustomerId().equals(customerId)) {
            throw new BusinessException(ErrorCode.ADDRESS_NO_PERMISSION);
        }

        // 清除其他默认地址
        addressMapper.clearDefaultFlag(customerId);

        // 设置当前地址为默认
        address.setIsDefault(true);
        addressMapper.setDefaultAddress(address);
    }

    @Override
    public List<AreaVO> areas(AreaQueryDTO queryDTO) {
        List<AreaVO> areaVOS = areaMapper.areas(queryDTO);
        if (CollUtil.isEmpty(areaVOS)) {
            return Collections.emptyList();
        }
        // 使用中文排序器
        Collator collator = Collator.getInstance(Locale.CHINA);

        areaVOS.sort((a1, a2) -> collator.compare(a1.getAreaName(), a2.getAreaName()));
        return areaVOS;
    }

}
